#!/bin/bash

# Zenith Mind Pro - Istio 服务网格安装脚本
# 支持 Linux 和 macOS

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        log_error "$1 命令未找到，请先安装 $1"
        exit 1
    fi
}

# 检查 Kubernetes 连接
check_k8s_connection() {
    log_info "检查 Kubernetes 集群连接..."
    if ! kubectl cluster-info &> /dev/null; then
        log_error "无法连接到 Kubernetes 集群，请检查 kubeconfig 配置"
        exit 1
    fi
    log_info "Kubernetes 集群连接正常"
}

# 安装 Istio
install_istio() {
    local ISTIO_VERSION=${1:-1.20.0}
    
    log_info "开始安装 Istio ${ISTIO_VERSION}..."
    
    # 检查是否已安装 istioctl
    if command -v istioctl &> /dev/null; then
        local current_version=$(istioctl version --client --short 2>/dev/null || echo "unknown")
        log_info "检测到已安装的 istioctl 版本: ${current_version}"
        
        read -p "是否要重新下载 Istio ${ISTIO_VERSION}? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "跳过 Istio 下载"
            return 0
        fi
    fi
    
    # 下载 Istio
    log_info "下载 Istio ${ISTIO_VERSION}..."
    curl -L https://istio.io/downloadIstio | ISTIO_VERSION=${ISTIO_VERSION} TARGET_ARCH=x86_64 sh -
    
    # 设置环境变量
    export PATH="$PWD/istio-${ISTIO_VERSION}/bin:$PATH"
    
    # 验证安装
    if ! command -v istioctl &> /dev/null; then
        log_error "Istio 安装失败"
        exit 1
    fi
    
    log_info "Istio 安装成功，版本: $(istioctl version --client --short)"
}

# 部署 Istio 到集群
deploy_istio() {
    log_info "部署 Istio 到 Kubernetes 集群..."
    
    # 预检查
    log_info "执行 Istio 预检查..."
    istioctl x precheck
    
    # 安装 Istio 控制平面
    log_info "安装 Istio 控制平面..."
    istioctl install --set values.defaultRevision=default -y
    
    # 等待 Istio 组件就绪
    log_info "等待 Istio 组件就绪..."
    kubectl wait --for=condition=ready pod -l app=istiod -n istio-system --timeout=300s
    
    # 安装 Istio Gateway
    log_info "部署 Istio Ingress Gateway..."
    kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/prometheus.yaml
    kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/grafana.yaml
    kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/jaeger.yaml
    kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/kiali.yaml
    
    # 验证安装
    log_info "验证 Istio 安装..."
    istioctl verify-install
    
    log_info "Istio 部署成功!"
}

# 创建命名空间并启用注入
setup_namespaces() {
    log_info "创建项目命名空间..."
    kubectl apply -f ../namespace.yaml
    
    log_info "为命名空间启用 Istio sidecar 注入..."
    kubectl label namespace zenith-mind istio-injection=enabled --overwrite
    kubectl label namespace zenith-mind-monitoring istio-injection=enabled --overwrite
    
    log_info "命名空间设置完成"
}

# 部署基础服务
deploy_base_services() {
    log_info "部署基础服务..."
    kubectl apply -f ../mysql.yaml
    kubectl apply -f ../redis.yaml
    kubectl apply -f ../nacos.yaml
    
    log_info "等待基础服务就绪..."
    kubectl wait --for=condition=ready pod -l app=mysql -n zenith-mind --timeout=300s
    kubectl wait --for=condition=ready pod -l app=redis -n zenith-mind --timeout=300s
    kubectl wait --for=condition=ready pod -l app=nacos -n zenith-mind --timeout=300s
    
    log_info "基础服务部署完成"
}

# 部署微服务
deploy_microservices() {
    log_info "部署微服务..."
    kubectl apply -f ../user-service.yaml
    kubectl apply -f ../gateway.yaml
    # 可以添加更多微服务部署
    
    log_info "等待微服务就绪..."
    kubectl wait --for=condition=ready pod -l app=zenith-user-service -n zenith-mind --timeout=300s
    kubectl wait --for=condition=ready pod -l app=zenith-gateway -n zenith-mind --timeout=300s
    
    log_info "微服务部署完成"
}

# 部署 Istio 配置
deploy_istio_config() {
    log_info "部署 Istio 配置..."
    kubectl apply -f gateway.yaml
    kubectl apply -f destination-rules.yaml
    kubectl apply -f security-policies.yaml
    kubectl apply -f observability.yaml
    
    log_info "Istio 配置部署完成"
}

# 验证部署
verify_deployment() {
    log_info "验证部署状态..."
    
    # 检查所有 Pod 状态
    kubectl get pods -n zenith-mind
    kubectl get pods -n istio-system
    
    # 检查 Istio 代理状态
    log_info "检查 Istio 代理状态..."
    istioctl proxy-status
    
    # 获取 Gateway 外部 IP
    log_info "获取 Ingress Gateway 访问地址..."
    kubectl get svc istio-ingressgateway -n istio-system
    
    log_info "部署验证完成"
}

# 显示访问信息
show_access_info() {
    log_info "=== 访问信息 ==="
    
    # Gateway IP
    GATEWAY_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo "pending")
    if [ "$GATEWAY_IP" = "pending" ] || [ -z "$GATEWAY_IP" ]; then
        GATEWAY_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.clusterIP}')
        log_warn "LoadBalancer IP 未分配，使用 ClusterIP: $GATEWAY_IP"
    fi
    
    echo "应用访问地址:"
    echo "  - API Gateway: http://$GATEWAY_IP"
    echo "  - 或使用端口转发: kubectl port-forward -n istio-system svc/istio-ingressgateway 8080:80"
    echo ""
    
    echo "监控面板:"
    echo "  - Kiali: kubectl port-forward -n istio-system svc/kiali 20001:20001"
    echo "  - Grafana: kubectl port-forward -n istio-system svc/grafana 3000:3000"
    echo "  - Jaeger: kubectl port-forward -n istio-system svc/jaeger 16686:16686"
    echo "  - Prometheus: kubectl port-forward -n istio-system svc/prometheus 9090:9090"
    echo ""
    
    echo "域名配置 (可选):"
    echo "  添加到 /etc/hosts 文件:"
    echo "  $GATEWAY_IP zenith-mind.local"
    echo "  $GATEWAY_IP api.zenith-mind.local"
}

# 主函数
main() {
    log_info "开始部署 Zenith Mind Pro 到 Istio 服务网格..."
    
    # 检查依赖
    check_command kubectl
    check_command curl
    check_k8s_connection
    
    # 安装和部署 Istio
    install_istio "${1:-1.20.0}"
    deploy_istio
    
    # 设置项目环境
    setup_namespaces
    
    # 部署服务
    deploy_base_services
    deploy_microservices
    deploy_istio_config
    
    # 验证和展示信息
    verify_deployment
    show_access_info
    
    log_info "Zenith Mind Pro Istio 部署完成!"
}

# 错误处理
trap 'log_error "部署过程中发生错误，退出"; exit 1' ERR

# 执行主函数
main "$@"